#pragma once

#include <string>
#include <vector>
#include <chrono>
#include <memory>

namespace El {
namespace Onvif {

/**
 * @brief ONVIF协议版本枚举
 */
enum class OnvifVersion {
    V2_0,
    V2_1,
    V2_2,
    V2_3,
    V2_4,
    V2_5,
    V2_6
};

/**
 * @brief 设备类型枚举
 */
enum class DeviceType {
    NETWORK_VIDEO_TRANSMITTER,  // NVT - 网络视频传输器
    NETWORK_VIDEO_STORAGE,      // NVS - 网络视频存储
    NETWORK_VIDEO_ANALYTICS,    // NVA - 网络视频分析
    NETWORK_VIDEO_DISPLAY,      // NVD - 网络视频显示
    NETWORK_VIDEO_CLIENT        // NVC - 网络视频客户端
};

/**
 * @brief 视频编码类型
 */
enum class VideoEncoding {
    JPEG,
    MPEG4,
    H264,
    H265
};

/**
 * @brief 音频编码类型
 */
enum class AudioEncoding {
    G711,
    G726,
    AAC,
    MP3
};

/**
 * @brief PTZ 移动状态
 */
enum class PTZMoveStatus {
    IDLE,
    MOVING,
    UNKNOWN
};

/**
 * @brief WS-Security 认证模式
 */
enum class SecurityMode {
    NONE,               // 无认证
    USERNAME_TOKEN,     // 用户名令牌
    DIGEST,            // 摘要认证
    WS_SECURITY        // WS-Security
};

/**
 * @brief 分辨率信息
 */
struct Resolution {
    int width{0};
    int height{0};

    Resolution() = default;
    Resolution(int w, int h) : width(w), height(h) {}

    bool operator==(const Resolution& other) const {
        return width == other.width && height == other.height;
    }
};

/**
 * @brief 时间范围
 */
struct TimeRange {
    std::chrono::system_clock::time_point from;
    std::chrono::system_clock::time_point until;
};

/**
 * @brief 设备信息
 */
struct DeviceInformation {
    std::string manufacturer;         // 制造商
    std::string model;               // 型号
    std::string firmwareVersion;     // 固件版本
    std::string serialNumber;        // 序列号
    std::string hardwareId;          // 硬件ID
};

/**
 * @brief 网络接口信息
 */
struct NetworkInterface {
    std::string token;               // 接口令牌
    bool enabled{true};              // 是否启用
    bool dhcp{false};               // 是否使用DHCP
    std::string ipAddress;          // IP地址
    int prefixLength{24};           // 子网掩码长度
    std::string gateway;            // 网关
    std::vector<std::string> dns;   // DNS服务器
    std::string macAddress;         // MAC地址
    int mtu{1500};                  // MTU
};

/**
 * @brief 视频源信息
 */
struct VideoSource {
    std::string token;              // 视频源令牌
    int framerate{25};              // 帧率
    Resolution resolution;          // 分辨率
    bool enabled{true};             // 是否启用
};

/**
 * @brief 音频源信息
 */
struct AudioSource {
    std::string token;              // 音频源令牌
    int channels{1};                // 声道数
    int sampleRate{8000};          // 采样率
    bool enabled{true};             // 是否启用
};

/**
 * @brief 视频编码器配置
 */
struct VideoEncoderConfiguration {
    std::string token;              // 配置令牌
    std::string name;               // 配置名称
    int useCount{0};                // 使用计数
    VideoEncoding encoding{VideoEncoding::H264};
    Resolution resolution;          // 编码分辨率
    float quality{5.0f};            // 质量等级 (1-10)
    struct {
        int frameRateLimit{25};     // 帧率限制
        int encodingInterval{1};    // 编码间隔
        int bitrateLimit{2048};     // 码率限制 (kbps)
    } rateControl;
    bool multicast{false};          // 是否支持组播
    std::string sessionTimeout{"PT60S"}; // 会话超时时间
};

/**
 * @brief 音频编码器配置
 */
struct AudioEncoderConfiguration {
    std::string token;              // 配置令牌
    std::string name;               // 配置名称
    int useCount{0};                // 使用计数
    AudioEncoding encoding{AudioEncoding::G711};
    int bitrate{64};                // 码率 (kbps)
    int sampleRate{8000};           // 采样率
    bool multicast{false};          // 是否支持组播
    std::string sessionTimeout{"PT60S"}; // 会话超时时间
};

/**
 * @brief 媒体配置文件
 */
struct MediaProfile {
    std::string token;              // 配置文件令牌
    std::string name;               // 配置文件名称
    bool fixed{false};              // 是否为固定配置文件
    
    // 关联的配置
    std::string videoSourceToken;
    std::string audioSourceToken;
    std::string videoEncoderToken;
    std::string audioEncoderToken;
    std::string ptzNodeToken;
    
    // 流媒体URI
    struct {
        std::string rtspUri;
        std::string rtmpUri;
        std::string hlsUri;
    } streamUris;
};

/**
 * @brief PTZ 位置信息
 */
struct PTZPosition {
    struct {
        float x{0.0f};              // 水平位置 (-1.0 到 1.0)
        float y{0.0f};              // 垂直位置 (-1.0 到 1.0)
    } panTilt;
    
    struct {
        float x{0.0f};              // 变焦位置 (0.0 到 1.0)
    } zoom;
};

/**
 * @brief PTZ 速度信息
 */
struct PTZSpeed {
    struct {
        float x{0.0f};              // 水平速度 (-1.0 到 1.0)
        float y{0.0f};              // 垂直速度 (-1.0 到 1.0)
    } panTilt;
    
    struct {
        float x{0.0f};              // 变焦速度 (-1.0 到 1.0)
    } zoom;
};

/**
 * @brief PTZ 节点信息
 */
struct PTZNode {
    std::string token;              // PTZ节点令牌
    std::string name;               // 节点名称
    bool fixedHomePosition{false};  // 是否有固定原点
    bool geoMove{false};            // 是否支持地理移动
    PTZPosition homePosition;       // 原点位置
    PTZSpeed maximumNumberOfPresets; // 最大预置点数量
};

/**
 * @brief PTZ 状态信息
 */
struct PTZStatus {
    PTZPosition position;           // 当前位置
    PTZMoveStatus moveStatus{PTZMoveStatus::IDLE}; // 移动状态
    std::string error;              // 错误信息
    std::chrono::system_clock::time_point utcTime; // UTC时间
};

/**
 * @brief 系统日期时间信息
 */
struct SystemDateTime {
    enum class DateTimeType {
        MANUAL,                     // 手动设置
        NTP                         // NTP同步
    } dateTimeType{DateTimeType::MANUAL};
    
    bool daylightSavings{false};    // 是否启用夏令时
    std::string timeZone{"UTC"};    // 时区
    std::chrono::system_clock::time_point utcDateTime; // UTC时间
    
    // NTP设置
    struct {
        bool fromDHCP{false};       // 是否从DHCP获取NTP服务器
        std::vector<std::string> ntpServers; // NTP服务器列表
    } ntp;
};

/**
 * @brief 用户信息
 */
struct User {
    std::string username;           // 用户名
    std::string password;           // 密码
    enum class UserLevel {
        ADMINISTRATOR,              // 管理员
        OPERATOR,                   // 操作员
        USER,                       // 普通用户
        ANONYMOUS,                  // 匿名用户
        EXTENDED                    // 扩展用户
    } userLevel{UserLevel::USER};
};

/**
 * @brief 作用域信息 (WS-Discovery)
 */
struct Scope {
    enum class ScopeDefinition {
        FIXED,                      // 固定作用域
        CONFIGURABLE               // 可配置作用域
    } scopeDef{ScopeDefinition::CONFIGURABLE};
    
    std::string scopeItem;          // 作用域项目
};

/**
 * @brief 服务能力信息
 */
struct ServiceCapabilities {
    // 设备管理服务能力
    struct {
        bool io{false};             // IO操作支持
        bool security{true};        // 安全功能支持
        bool systemBackup{false};   // 系统备份支持
        bool systemLogging{true};   // 系统日志支持
        bool firmwareUpgrade{true}; // 固件升级支持
        int maxUsers{10};           // 最大用户数
    } device;
    
    // 媒体服务能力
    struct {
        bool videoSources{true};    // 视频源支持
        bool audioSources{true};    // 音频源支持
        bool rtpMulticast{false};   // RTP组播支持
        bool rotation{false};       // 旋转支持
        bool videoSourceMode{false}; // 视频源模式支持
        bool osd{true};             // OSD支持
        bool exiCompression{false}; // EXI压缩支持
        int maxProfiles{10};        // 最大配置文件数
    } media;
    
    // PTZ服务能力
    struct {
        bool eFlip{false};          // 电子翻转支持
        bool reverse{false};        // 反转支持
        bool getCompatibleConfiguration{true}; // 兼容配置获取
        bool moveStatus{true};      // 移动状态支持
        bool statusPosition{true};  // 状态位置支持
    } ptz;
};

/**
 * @brief SOAP 消息封装
 */
struct SoapMessage {
    std::string action;             // SOAP Action
    std::string body;               // 消息体
    std::string header;             // 消息头
    std::string messageId;          // 消息ID
    std::string replyTo;            // 回复地址
    std::string to;                 // 目标地址
    SecurityMode securityMode{SecurityMode::NONE}; // 安全模式
    std::string username;           // 用户名 (用于认证)
    std::string password;           // 密码 (用于认证)
    std::string nonce;              // 随机数 (用于认证)
    std::string created;            // 创建时间 (用于认证)
    bool hasWSSecurity{false};      // 是否有WS-Security
};

/**
 * @brief ONVIF 服务端点信息
 */
struct ServiceEndpoint {
    std::string namespace_;         // 命名空间
    std::string address;            // 服务地址
    int port{80};                   // 服务端口
    std::string path;               // 服务路径
    bool isSecure{false};           // 是否使用HTTPS
};

using OnvifTimestamp = std::chrono::system_clock::time_point;
using TokenType = std::string;

} // namespace Onvif
} // namespace El 